import urllib.request
import urllib.error  # 制定url，获取网页数据
from bs4 import BeautifulSoup  # 解析网页
import re  # 正则表达式
import os
import csv

# 爬取的地址以及保存的文件名
BASE_URL = "https://movie.douban.com/chart"
CSV_PATH = "../豆瓣新片榜.csv"

# 影片详情链接
FIND_LIST = re.compile(r'<a href="(.*?)">')  # 创建正则表达式对象，表示规则（字符串的模式）
# 影片图片
FIND_IMG = re.compile(r'<img[^>]*src="([^"]+)"[^>]*>', re.S)  # re.S让换行包含在字符中
# 影片中文片名
FIND_TITLE = re.compile(r'<img[^>]*alt="([^"]+)"[^>]*>')
# 影片其他片名
FIND_TITLE2 = re.compile(r'<span style="font-size:13px;">(.*?)</span>')
# 找到影片的相关内容
FIND_TBG = re.compile(r'<p>(.*?)</p>', re.S)
# 影片评分
FIND_Rating = re.compile(r'<span class="rating_nums">(.*?)</span>')
# 评价人数
FIND_JUDGE = re.compile(r'\((\d+)人评价\)')


def main():
    """主函数：协调数据爬取、解析和存储流程"""
    # 1.爬取数据
    movie_data = get_movie_data(BASE_URL)

    # 2.保存数据
    save_to_csv(movie_data, CSV_PATH)

    print("影片TOP爬取完毕")


def get_movie_data(baseurl):
    """爬取网页数据"""
    datalist = []
    html = ask_url(baseurl)

    # 逐一解析数据
    soup = BeautifulSoup(html, 'html.parser')  # 后面是解析器
    for item in soup.find_all('tr', class_="item"):  # 查找符合要求的字符串，形成列表
        data = []  # 一部电影的所有信息
        item = str(item)

        # 获取影片详情的链接
        link = re.findall(FIND_LIST, item)[0]
        data.append(link)

        # 获取影片图片链接
        img_src = re.findall(FIND_IMG, item)[0]
        data.append(img_src)

        # 获取影片中文片名
        c_title = re.findall(FIND_TITLE, item)[0]
        data.append(c_title)

        # 获取影片其他片名
        o_title = re.findall(FIND_TITLE2, item)[0]
        data.append(o_title)

        # 电影背景信息
        bd = re.findall(FIND_TBG, item)[0]
        data.append(bd)

        # 获取影片评分
        rating = re.findall(FIND_Rating, item)
        if len(rating) > 0:
            rating = rating[0]
            data.append(rating)
        else:
            data.append(" ")

        # 获取评价人数
        judge_num = re.findall(FIND_JUDGE, item)
        if len(judge_num) > 0:
            judge_num = judge_num[0]
            data.append(judge_num)
        else:
            data.append(" ")

        datalist.append(data)  # 把处理好的信息放入datalist中

    return datalist


def ask_url(url):
    """获取指定URL的HTML内容"""
    head = {
        "User-Agent": "Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Mobile Safari/537.36 Edg/137.0.0.0"
    }
    html = ""

    try:
        req = urllib.request.Request(url, headers=head)
        with urllib.request.urlopen(req) as response:
            html = response.read().decode('utf-8')
    except Exception as e:
        print("请求失败:", e)

    return html


def save_to_csv(datalist, csv_path):
    """使用csv模块保存数据"""
    headers = ('电影详情链接', '电影图片链接', '影片中文名', '影片外国名', '相关内容', '评分', '评价数量')

    # 若存在文件，那么覆盖
    if os.path.exists(csv_path):
        os.remove(csv_path)

    try:
        with open(csv_path, 'w', newline='', encoding='utf-8-sig') as csv_file:
            writer = csv.writer(csv_file)
            writer.writerow(headers)

            for i, data in enumerate(datalist, 1):
                print(f"正在写入第 {i} 条csv数据")

                # 处理每个字段，确保没有换行符和多余空格等
                cleaned_data = [
                    str(field)
                    .replace('\n', '，')
                    .replace('\r', '，')
                    .replace('<br>', '，')
                    .replace(' ', '')
                    .strip() for field in data
                ]
                writer.writerow(cleaned_data)

        print(f"数据已成功保存到 {csv_path}")
    except Exception as e:
        print(f"保存CSV文件时出错: {e}")  # 保存数据


if __name__ == '__main__':
    main()
    print("爬取完毕")
